package com.hyx.api.service.impl.pc_admin;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hyx.api.domain.Model;
import com.hyx.api.mapper.ModelMapper;
import com.hyx.api.service.pc_admin.IAdminService;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.mapper.SysDictDataMapper;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;

@Service
public class AdminServiceImpl implements IAdminService {

    @Autowired
    private SysDictDataMapper dictDataMapper;
    @Autowired
    private ModelMapper modelMapper;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult importModels(MultipartFile file) {
        String fileName = file.getOriginalFilename();
        if (!fileName.matches("^.+\\.(?i)(xls)$") && !fileName.matches("^.+\\.(?i)(xlsx)$")) {
            throw new ServiceException("上传文件格式不正确");
        }
        boolean isExcel2003 = !fileName.matches("^.+\\.(?i)(xlsx)$");
        Workbook wb = null;
        try {
            InputStream is = file.getInputStream();
            wb = isExcel2003 ? new HSSFWorkbook(is) : new XSSFWorkbook(is);
        } catch (IOException e) {
            throw new ServiceException("读取文件流失败");
        }
        Sheet sheet = wb.getSheetAt(0);
        if (sheet == null) {
            throw new ServiceException("导入文件未获取到数据");
        }
        Row row = sheet.getRow(sheet.getFirstRowNum());
        String nameDesc = "", dictCodeDesc = "", operatorOSDesc = "", specificationDesc = "";
        if (row.getCell(0) != null) {
            nameDesc = row.getCell(0).toString().trim();
        }
        if (row.getCell(1) != null) {
            dictCodeDesc = row.getCell(1).toString().trim();
        }
        if (row.getCell(2) != null) {
            operatorOSDesc = row.getCell(2).toString().trim();
        }
        if (row.getCell(3) != null) {
            specificationDesc = row.getCell(3).toString().trim();
        }
        if (!"名称".equals(nameDesc) || !dictCodeDesc.contains("字典编码")
                || !operatorOSDesc.contains("操作系统") || !specificationDesc.contains("规格选项")) {
            throw new ServiceException("模板格式不正确");
        }
        StringBuilder errorInfo = new StringBuilder();
        for (int i = sheet.getFirstRowNum() + 1, j = i + 1; i <= sheet.getLastRowNum(); i++, j++) {
            row = sheet.getRow(i);
            if (row == null) {
                continue;
            }
            //定义数据值
            String name = null;
            Long dictCode = null;
            Integer operatorOS = null;
            String specification = null;

            //机型名称
            if (row.getCell(0) != null) {
                name = row.getCell(0).toString().trim();
            }
            if (StringUtils.isBlank(name)) {
                errorInfo.append(String.format("第（%s）行：机型名称为空<br/>", j));
            }
            //字典编码
            if (row.getCell(1) != null) {
                dictCode = (long) (Double.parseDouble(row.getCell(1).toString().trim()));
            }
            if (dictCode == null) {
                errorInfo.append(String.format("第（%s）行：字典编码为空<br/>", j));
            } else {
                SysDictData dictData = dictDataMapper.selectDictDataById(dictCode);
                if (dictData == null) {
                    errorInfo.append(String.format("第（%s）行：字典编码错误，没有建立该字符编码<br/>", j));
                }
            }
            //操作系统
            if (row.getCell(2) != null) {
                operatorOS = (int)(Double.parseDouble(row.getCell(2).toString().trim()));
            }
            if (operatorOS == null) {
                errorInfo.append(String.format("第（%s）行：操作系统为空<br/>", j));
            } else {
                if (operatorOS < 0 || operatorOS > 1) {
                    errorInfo.append(String.format("第（%s）行：操作系统有误<br/>", j));
                }
            }
            //规格选项
            if (row.getCell(3) != null) {
                specification = row.getCell(3).toString().trim();
            }
            JSONObject specificationJson = new JSONObject();
            if (StringUtils.isBlank(specification)) {
                errorInfo.append(String.format("第（%s）行：规格选项为空<br/>", j));
            } else {
                String[] specificationKeys = specification.split(",");
                if (specificationKeys.length > 0) {
                    for (String specificationKey : specificationKeys) {
                        String[] specificationValue = specificationKey.split(":");
                        if (specificationValue.length > 1) {
                            specificationJson.put(specificationValue[0], specificationValue[1]);
                        } else {
                            errorInfo.append(String.format("第（%s）行：规格选项有误<br/>", j));
                            break;
                        }
                    }
                }
            }
            //数据检查有误则不在执行后续数据库插入操作
            if (!errorInfo.toString().isEmpty()) {
                continue;
            }
            //防止重复新增
            QueryWrapper<Model> modelWrapper = new QueryWrapper<>();
            modelWrapper.eq("model_type_code", dictCode).eq("name", name);
            Long modelCount = modelMapper.selectCount(modelWrapper);
            if (modelCount > 0) {
                continue;
            }
            Model modelDO = new Model();
            //modelDO.setModelTypeCode(dictCode);
            modelDO.setName(name);
            modelDO.setSystemType(String.valueOf(operatorOS));
            modelDO.setSpecsJson(specificationJson.toJSONString());
            modelMapper.insert(modelDO);
        }
        //如果有异常信息发生则抛出异常，数据库自动回滚
        if (!errorInfo.toString().isEmpty()) {
            throw new ServiceException(errorInfo.toString());
        }
        return AjaxResult.success();
    }
}
